package com.yungam.other.mes_controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.yungam.common.bean.equip.Equipment;
import com.yungam.common.bean.equip.EquipmentCollectorMap;
import com.yungam.common.bean.process.ProcessInspection;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.product.ProductionProduct;
import com.yungam.common.bean.work_order.WorkOrderProduct;
import com.yungam.common.service.*;import com.yungam.other.response.ResData;
import com.yungam.other.service.IotService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 下发开始采集指令接口
 */
@Slf4j
@RestController
public class SendStartCommandController {

    @Resource
    private WorkOrderProductService workOrderProductService;
    @Resource
    private ProductProcessService productProcessService;
    @Resource
    private EquipmentService equipmentService;
    @Resource
    private ProductionProductService productionProductService;
    @Resource
    private ProcessInspectionService processInspectionService;
    @Resource
    private ProductionProcessService productionProcessService;
    @Resource
    private EquipmentCollectorMapService equipmentCollectorMapService;
    @Resource
    private IotService iotService;

    @PostMapping("IMCS/sendStartCommand")
    public Map<String, Object> sendStartCommand(@RequestBody Map<String, Object> params) {
        log.info("========= START『mes调用imcs』[下发开始采集指令接口]=========");
        log.info("=========『mes数据』{}", new Gson().toJson(params));
        // 处理参数
        String trackingId = String.valueOf(params.get("trackingId")), productSn = String.valueOf(params.get("productSn")),
                processNo = String.valueOf(params.get("processNo")),  stationId = String.valueOf(params.get("stationId"));
        log.info("『进站』productSn === " + productSn + " , processNo === " + processNo);
        // Step 1. 判断产品罐号是否存在
        WorkOrderProduct wop =
                workOrderProductService.getOne(new QueryWrapper<WorkOrderProduct>().eq("product_sn", productSn));
        if (wop == null) {
            log.error("罐号不存在");
            return ResData.error("罐号不存在");
        }

        // Step 2. 根据产品代号、工序号, 判断产品工序是否存在
        ProductProcess pp = productProcessService.getOne(new QueryWrapper<ProductProcess>().eq("product_no", wop.getProductNo())
                .eq("process_no", processNo));
        if (pp == null) {
            log.error("产品工序不存在");
            return ResData.error("产品工序不存在");
        }

        // Step 3. (如果工位存在) 根据工位编号获取设备编号
        Equipment equipment = null;
        if (stationId != null) {
            equipment = equipmentService.getOne(new QueryWrapper<Equipment>().eq("station_no", stationId));
        }

        // Step 4. 生成产品质量数据 production_product (先根据罐号查询, 如果没有则生成)
        ProductionProduct exist = productionProductService.getOne(new QueryWrapper<ProductionProduct>()
                .eq("product_sn", productSn));
        if (exist == null) {
            ProductionProduct addPp = new ProductionProduct();
            addPp.setProductNo(pp.getProductNo());
            addPp.setProductSn(productSn);
            addPp.setState(0);                 // 状态: 生产中
            addPp.setStartTime(new Date());   // 产品生产开始时间
            productionProductService.save(addPp);
        }

        // Step 5. 工序质量数据
        ProductionProcess newProProcess = new ProductionProcess();
        newProProcess.setProductSn(productSn);
        newProProcess.setProcessNo(processNo);
        newProProcess.setProcessName(pp.getProcessName());
        newProProcess.setProductNo(pp.getProductNo());
        if (equipment != null) newProProcess.setEquNo(equipment.getEquNumber());
        newProProcess.setState(0); // 未完成
        newProProcess.setStartTime(new Date());
        newProProcess.setTrackingId(trackingId);
        // 查询阈值信息 process_inspection
        List<ProcessInspection> ins = processInspectionService
                .list(new QueryWrapper<ProcessInspection>().eq("process_id", pp.getProcessId()));
        if (ins.size() > 0) newProProcess.setInspectionInfo(JSON.toJSONString(ins));

        // 基本逻辑: 先根据 productSn & processNo (如果设备存在, 则加入设备编号的查询条件 防止一个工序多个设备)
        // 查询 production_process => 1. 不存在, 则插入  ||  2. 存在, 则更新
        QueryWrapper<ProductionProcess> queryWrapper = new QueryWrapper<ProductionProcess>()
                .eq("product_sn", productSn).eq("process_no", processNo);
        if (equipment != null) queryWrapper.eq("equ_no", equipment.getEquNumber());
        ProductionProcess pdProcess = productionProcessService.getOne(queryWrapper);
        if (pdProcess == null) {
            productionProcessService.save(newProProcess);
        } else {
            newProProcess.setQualityId(pdProcess.getQualityId());
            productionProcessService.updateById(newProProcess);
        }

        // Step 5. 通知 IOT 端
        if (equipment != null) {
            String ip = equipment.getEquIp();
            if (ip == null) {
                log.error("工位对应设备信息不存在");
                return ResData.error("工位对应设备信息不存在");
            }
            // 查询对应的采集器 ip
            EquipmentCollectorMap cMap = equipmentCollectorMapService.getOne(new QueryWrapper<EquipmentCollectorMap>()
                    .eq("equ_ip", ip));
            if (cMap != null && cMap.getCollectorIp() != null) {
                // 调用设备接口, 通知扫码开始
                log.info("『调用IOT接口』扫码开始 => equIp === " + equipment.getEquIp() + " => collectorIp === " + cMap.getCollectorIp());
                iotService.equipScanStartAdvice(ip, cMap.getCollectorIp());
            }
        }

        log.info("进站成功");
        return ResData.success("进站下发指令成功");
    }
}
